package com.bst.bsj.biz.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bst.bsj.biz.RedisLockHandler;
import com.bst.bsj.biz.RedisLockService;
import com.bst.bsj.biz.WeixinService;
import com.bst.bsj.front.FrontConstants;
import com.bst.bsj.portal.util.RedisKeyCatConstants;
import com.bst.bsj.portal.util.RedisKeyUtil;
import com.bst.bsj.weixin.APIBaseSupport;
import com.bst.bsj.weixin.WeixinConfig;
import com.bst.bsj.weixin.WeixinJSSDK;
import com.homewaimai.biz.cache.store.redis.IRedisTemplate;
import com.homewaimai.common.lang.Result;
import com.homewaimai.common.lang.ResultSupport;
import com.homewaimai.common.lang.StringUtil;

@Service("weixinService")
public class WeixinServiceImpl  implements WeixinService {

    private static final Log      logger = LogFactory.getLog(WeixinServiceImpl.class);

    @Autowired
    private IRedisTemplate        sharedRedisTemplate;

    @Autowired
    private RedisLockService      redisLockService;

  
    public String createJsapiTicket(WeixinConfig wxpayconfig) {

        final String access_token = createAccessToken(wxpayconfig);

        if (StringUtil.isBlank(access_token)) {
            return null;
        }

        String mpprefix = "";
        // 平台名称前缀
        final String key = RedisKeyUtil.assemblyServiceKey(RedisKeyCatConstants.WXJSSDK, mpprefix);
        String ticket = sharedRedisTemplate.get(key);
        if (StringUtil.isNotEmpty(ticket)) {
            return ticket;
        }
        String lock_mux = RedisKeyUtil.assemblyServiceKey(key, FrontConstants.JSAPI_TICKET_UPDATE_MUX);
        Result result = redisLockService.exeLock(new RedisLockHandler() {

            public Result exec() {
                // 获取访问token
                int count = 0;
                String tt = null;
                do {
                    tt = WeixinJSSDK.getJsApiTicket(access_token);
                    count = count + 1;
                } while (StringUtil.isBlank(tt) && count < 3);
                // 设置访问token的失效时间为7000秒
                sharedRedisTemplate.setex(key, FrontConstants.JSAPI_TICKET_EXPIRE, tt);
                Result result = new ResultSupport(false);
                if (StringUtil.isNotBlank(tt)) {
                    result.setSuccess(true);
                    result.getModels().put(RedisKeyCatConstants.WXJSSDK, tt);
                    return result;
                }
                result.setSuccess(false);
                result.setDefaultModel("code", "501");
                result.setDefaultModel("data", "APIBaseSupport.getAccessToken 出错");
                return result;
            }
        }, lock_mux);
        if (result.isSuccess()) {
            return (String) result.getModels().get(RedisKeyCatConstants.WXJSSDK);
        }
        logger.error("getJsApiTicket error:" + result.getModels().get("data"));
        return null;
    }


    public String createAccessToken(WeixinConfig wxpayconfig) {
        final String appId = wxpayconfig.getAppId();
        String mpprefix = RedisKeyUtil.assemblyServiceKey(RedisKeyCatConstants.WXAPI, appId);
        // String mpprefix = RedisKeyUtil.assemblyServiceKey(RedisKeyCatConstants.WXAPI, wxpayconfig.getMid());
        final String at_key = RedisKeyUtil.assemblyServiceKey(mpprefix, FrontConstants.ACCESS_TOKEN);
        String accessToken = sharedRedisTemplate.get(at_key);
        if (StringUtil.isNotEmpty(accessToken)) {
            return accessToken;
        }
        // access_token 重新取。
        logger.info("access_token retrieval. time:" + System.currentTimeMillis());
        final String appSecret = wxpayconfig.getAppSecret();
        String lock_mux = RedisKeyUtil.assemblyServiceKey(mpprefix, FrontConstants.ACCESS_TOKEN_UPDATE_MUX);
        Result result = redisLockService.exeLock(new RedisLockHandler() {

            public Result exec() {
                // 获取访问token
                String at = null;
                int count = 0;
                do {
                    at = APIBaseSupport.getAccessToken(appId, appSecret);
                    count = count + 1;
                } while (StringUtil.isBlank(at) && count < 3);
                // 设置访问token的失效时间为7000秒
                sharedRedisTemplate.setex(at_key, FrontConstants.ACCESS_TOKEN_EXPIRE, at);
                Result result = new ResultSupport(false);
                if (StringUtil.isNotBlank(at)) {
                    result.setSuccess(true);
                    result.getModels().put(FrontConstants.ACCESS_TOKEN, at);
                    return result;
                }
                result.setSuccess(false);
                result.setDefaultModel("code", "501");
                result.setDefaultModel("data", "APIBaseSupport.getAccessToken 出错");
                return result;
            }
        }, lock_mux);
        if (result.isSuccess()) {
            return (String) result.getModels().get(FrontConstants.ACCESS_TOKEN);
        }
        logger.error("getAccessToken error:" + result.getModels().get("data"));
        return null;
    }

}
